import datetime
import time

from django.conf import settings

from django.core.cache import cache
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

from django.db import transaction
from django.db.models import Q
from django.http import JsonResponse
from django.views import View
import json

from django_redis import get_redis_connection

from homes.models import Area, House, HouseImage
from homes.utils import house_data
from libs.qiniuyun.qiniu_storage import storage
from order.models import Order
from users.models import User
from utils.view import LoginRequiredMixin

import logging

logger = logging.getLogger('django')


class Country(View):

    def get(self, request):
        area_list = cache.get('area_list')
        if not area_list:
            try:
                areas = Area.objects.all()
            except Exception as e:
                JsonResponse({"errno": "400",
                              "errmsg": "查询数据库失败"})
            area_list = []
            for area in areas:
                area_list.append({
                    'aid': area.id,
                    'aname': area.name
                })
            cache.set('area_list', area_list, 3600)
        return JsonResponse({
            "errmsg": "获取成功",
            "errno": "0",
            "data": area_list
        })


class ShowhouseView(LoginRequiredMixin, View):
    def get(self, request):
        # 显示所有房源
        try:
            houses = House.objects.filter(user=request.user)
        except Exception as e:
            return JsonResponse({'errno': 400, 'errmsg': '获取房源失败'})
        list = []
        for house in houses:
            dict = {
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time,
                "house_id": house.id,
                "img_url": settings.QINIU_URL + str(house.index_image_url),
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": settings.QINIU_URL + str(house.user.avatar)
            }
            list.append(dict)
        return JsonResponse({'errno': 0, 'errmsg': 'ok', 'data': {'houses': list}})


class HousesView(View):
    """发布新房源"""

    def post(self, request):
        json_dict = json.loads(request.body.decode())
        title = json_dict.get('title')
        price = json_dict.get('price')
        area_id = json_dict.get('area_id')
        address = json_dict.get('address')
        room_count = json_dict.get('room_count')
        acreage = json_dict.get('acreage')
        unit = json_dict.get('unit')
        capacity = json_dict.get('capacity')
        beds = json_dict.get('beds')
        deposit = json_dict.get('deposit')
        min_days = json_dict.get('min_days')
        max_days = json_dict.get('max_days')
        facility = json_dict.get('facility')
        if not all([title, price, area_id, address, room_count, acreage,
                    unit, capacity, beds, deposit, min_days, max_days, facility]):
            return JsonResponse({'errno': 400,
                                 'errmsg': '缺少必传参数'})
        if int(max_days) != 0 and int(max_days) < int(min_days):
            return JsonResponse({'errno': 400,
                                 'errmsg': '最大租房时间应大等于最小租房时间'})
        try:
            house = House.objects.create(user_id=request.user.id, title=title, price=price, area_id=area_id,
                                         address=address, room_count=room_count, acreage=acreage,
                                         unit=unit, capacity=capacity, beds=beds, deposit=deposit, min_days=min_days,
                                         max_days=max_days)
            # 多对多数据表操作
            for facility_info in facility:
                house.facility.add(facility_info)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400,
                                 'errmsg': '数据存储错误'})
        return JsonResponse({
            "errno": "0",
            "errmsg": "发布成功",
            "data": {"house_id": house.id}
        })

        # 房屋数据搜索
    def get(self, request):
        # 1.接收参数
        aid = request.GET.get('aid')
        start_day = request.GET.get('sd')
        end_day = request.GET.get('ed')
        sort_ket = request.GET.get('sk', 'new')
        page = request.GET.get('p', '1')

        # 2.验证
        if not all([aid, start_day, end_day]):
            return JsonResponse({'erron': 4103, 'errmsg': '参数错误'})

        # 3.查询数据库
        # 时间校验与查询数据

        if start_day:
            startday = datetime.datetime.strptime(start_day, '%Y-%m-%d')
            if end_day:
                endday = datetime.datetime.strptime(end_day, '%Y-%m-%d')
                if startday > endday:
                    return JsonResponse({'erron': 4103, 'errmsg': '参数错误'})
                else:
                    try:
                        houses = House.objects.filter(area_id=aid)
                        # 开始时间<结束时间 结束时间>开始时间
                        orders = Order.objects.filter(begin_date__lt=endday, end_date__gt=start_day, house__in=houses,
                                                      status__in=[0, 1, 2, 3, 4])
                        # 查询订单中的房屋id
                        if not orders:
                            if sort_ket:
                                if sort_ket == 'booking':
                                    houses = House.objects.filter(area_id=aid).order_by('-order_count')
                                elif sort_ket == 'price-inc':
                                    houses = House.objects.filter(area_id=aid).order_by('price')
                                elif sort_ket == 'price-des':
                                    houses = House.objects.filter(area_id=aid).order_by('-price')
                                else:
                                    houses = House.objects.filter(area_id=aid).order_by('-create_time')

                                data = house_data(houses, page)

                                # 4.返回响应
                                return JsonResponse({"errno": 0, "errmsg": "请求成功", "data": data})

                        house_id_list = []
                        for order in orders:
                            house = order.house
                            if house.area_id == aid:
                                house_id_list.append(house.id)
                            house_id_list.append(order.house.id)

                        # 获取所有除订单中的房屋对象
                        # House.objects.exclude(id__in=house_id_list)
                        if sort_ket:
                            if sort_ket == 'booking':
                                houses = House.objects.filter(~Q(id__in=house_id_list) & Q(area_id=aid)).order_by(
                                    '-order_count')
                            elif sort_ket == 'price-inc':
                                houses = House.objects.filter(~Q(id__in=house_id_list) & Q(area_id=aid)).order_by(
                                    'price')
                            elif sort_ket == 'price-des':
                                houses = House.objects.filter(~Q(id__in=house_id_list) & Q(area_id=aid)).order_by(
                                    '-price')
                            else:
                                houses = House.objects.filter(~Q(id__in=house_id_list) & Q(area_id=aid)).order_by(
                                    '-create_time')

                            data = house_data(houses, page)

                            # 4.返回响应
                            return JsonResponse({"errno": 0, "errmsg": "请求成功", "data": data})

                    except Exception as e:
                        logger.error(e)
                        return JsonResponse({'erron': 4004, 'errmsg': '数据错误'})
# 上传房源图片
class HouseImagesView(LoginRequiredMixin, View):

    def post(self, request, house_id):
        house_image = request.FILES.get('house_image')
        redis_code = get_redis_connection('image_code')
        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400, 'errmsg': 'mysql读取错误'})
        try:
            image_server = redis_code.get('image_%s' % str(house_image))
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400, 'errmsg': 'redis读取错误'})
        if image_server:
            if image_server.decode() == str(house_image):
                return JsonResponse({'errno': 4001, 'errmsg': '图片名重复'})
        # 防止用户短时间内上传同一种图片
        try:
            redis_conn = get_redis_connection('image_code')
            redis_conn.setex('image_%s' % str(house_image), 600, str(house_image))
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400, 'errmsg': 'redis写入错误'})
        try:
            image_url = storage(house_image.read())
        except Exception as e:
            logger.error(e)
            return JsonResponse({'errno': 400, 'errmsg': '上传失败'})
        with transaction.atomic():
            save_id = transaction.savepoint()
            try:
                HouseImage.objects.create(house_id=house_id, url=image_url)
                if not house.index_image_url:
                    house.index_image_url = image_url
                    house.save()

            except Exception as e:
                logger.error(e)
                transaction.savepoint_rollback(save_id)
                return JsonResponse({'errno': 400, 'errmsg': 'mysql保存图片地址失败'})
        transaction.savepoint_commit(save_id)
        data = {
            'url':settings.QINIU_URL + str(image_url)
        }

        return JsonResponse({"data": data,"errno": "0","errmsg": "图片上传成功"})




class ShowallhouseView(View):
    # 首页显示房源
    def get(self, request):
        try:
            houses = House.objects.order_by('order_count')[:5]
        except Exception as e:
            return JsonResponse({'errno': 400, 'errmsg': '加载地址失败'})
        data = []
        for house in houses:
            data.append({
                "house_id": house.id,
                "img_url": settings.QINIU_URL + str(house.index_image_url),
                "title": house.title})
        return JsonResponse({'errno': 0, 'errmsg': 'ok', 'data': data})


class HouseInfoView(View):
    #房源详情展示
    def get(self, request, house_id):
        try:
            house = House.objects.get(id=house_id)
        except Exception as e:
            return JsonResponse({'errno': 400, 'errmsg': '房屋id不存在'})
        # 根据house查询对应的订单
        comments_list = []
        try:
            order_item = Order.objects.filter(house=house)
        except Exception as e:
            return JsonResponse({'errno': 400, 'errmsg': '数据库操作失败'})

        for order in order_item:
            comments_list.append({
                'comment': order.comment,
                'ctime': order.create_time,
                'user_name': order.user.username
            })
        # 房屋图片列表
        img_url_list = []
        try:
            house_img_item = HouseImage.objects.filter(house=house)
        except Exception as e:
            return JsonResponse({'errno': 400, 'errmsg': '数据库操作失败'})
        for house_img in house_img_item:
            img_url_list.append(settings.QINIU_URL + house_img.url)

        # 设施表
        facility_list = []
        for facility in house.facility.all():
            facility_list.append(facility.id)

        house_dict = {
            'acreage': house.acreage,
            'address': house.address,
            'beds': house.beds,
            'capacity': house.capacity,
            'comments': comments_list,
            'deposit': house.deposit,
            'facilities': facility_list,
            'hid': house.id,
            'img_urls': img_url_list,
            'max_days': house.max_days,
            'min_days': house.min_days,
            'price': house.price,
            'room_count': house.room_count,
            'title': house.title,
            'unit': house.unit,
            'user_avatar': settings.QINIU_URL + str(house.user.avatar),
            'user_id': int(house.user.id),
            'user_name': house.user.username,
        }
        if request.user.is_authenticated:
            house_info = {'house': house_dict, 'user_id': request.user.id}
        else:
            house_info = {'house': house_dict, 'user_id': -1}
        return JsonResponse({'errno': 0, 'errmsg': 'ok', "data": house_info})
